#include <stdio.h>
#include <string.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

// 服务器的ip
#define SERVER_IP "192.168.2.146" // 自己的ubuntu的ip
// 服务器的端口
#define SERVER_PORT 60000 // 1024-65535

// 自己的ip和端口
#define MY_IP "192.168.2.146"
#define MY_PORT 60003

#define TARGET_IP "192.168.2.147"
#define TARGET_PORT 60001

// 定义发送信息的结构体(自定义)
struct msg
{
    char buf[1024];
    char name[20];
    char passward[20];
    struct sockaddr_in other_addr;
    int flag; // 用来区分注册 登录 还是发送信息
};

// 接收消息的线程函数
void *receive_messages(void *arg)
{
    int socket_fd = *(int *)arg;
    char buf[1024];
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        int recv_len = recv(socket_fd, buf, sizeof(buf), 0);
        if (recv_len <= 0)
        {
            printf("Server disconnected or error occurred.\n");
            break;
        }
        printf("Received from server: %s\n", buf);
    }
    return NULL;
}

/*
    tcp客户端
*/
int main(int argc, char **argv)
{
    int ret = 0;

    // 创建套接字(socket)
    // AF_INET:ipv4 SOCK_STREAM:tcp协议
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0)
    {
        printf("socket fail\n");
        return -1;
    }

    // 客户端如果不绑定 端口号随机；如果绑定 端口号是固定的；
    int optval = 1;
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    struct sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(MY_PORT);
    my_addr.sin_addr.s_addr = inet_addr(MY_IP);
    ret = bind(socket_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in));
    if (ret < 0)
    {
        printf("bind fail\n");
        return -1;
    }

    // 填充服务器的ip地址和端口
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);

    // 连接客户端(connect)
    ret = connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    if (ret < 0)
    {
        printf("connect server fail\n");
        return -1;
    }
    printf("连接服务器成功[%s][%d][%d]\n", SERVER_IP, SERVER_PORT, socket_fd);

    // 发送登录消息
    struct msg login_msg;
    memset(&login_msg, 0, sizeof(login_msg));
    strcpy(login_msg.name, "client2");
    strcpy(login_msg.passward, "password");
    login_msg.flag = 2;
    ret = send(socket_fd, &login_msg, sizeof(login_msg), 0);
    if (ret < 0)
    {
        printf("send login msg fail\n");
        return -1;
    }

    // 创建接收消息的线程
    pthread_t receive_thread;
    ret = pthread_create(&receive_thread, NULL, receive_messages, &socket_fd);
    if (ret != 0)
    {
        printf("Failed to create receive thread.\n");
        return -1;
    }

    // 填充目标客户端信息（这里假设已知client1的IP和端口）
    struct sockaddr_in target_addr;
    target_addr.sin_family = AF_INET;
    target_addr.sin_port = htons(TARGET_PORT);          // client1的端口
    target_addr.sin_addr.s_addr = inet_addr(TARGET_IP); // client1的IP

    char buf[1024] = {0};
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        fgets(buf, sizeof(buf), stdin); // 这个字符串可以带空格

        struct msg chat_msg;
        memset(&chat_msg, 0, sizeof(chat_msg));
        strcpy(chat_msg.name, "client2");
        strcpy(chat_msg.buf, buf);
        chat_msg.flag = 3;
        chat_msg.other_addr = target_addr;

        ret = send(socket_fd, &chat_msg, sizeof(chat_msg), 0);
        if (ret < 0)
        {
            printf("send fail\n");
            return -1;
        }
        printf("send success ret:%d\n", ret);

        char buf[1024] = {0};
        while (1)
        {
            // 设置目标地址
            struct sockaddr_in target_addr;
            scanf("%s",chat_msg.buf);
            memset(&target_addr, 0, sizeof(target_addr));
            target_addr.sin_family = AF_INET;
            target_addr.sin_port = htons(TARGET_PORT);
            inet_pton(AF_INET, TARGET_IP, &target_addr.sin_addr);
            chat_msg.other_addr = target_addr;

            send(socket_fd, &chat_msg, sizeof(chat_msg), 0);
            printf("消息已发送: %s\n", chat_msg.buf);
        }
    }

    // 等待接收线程结束（实际上不会执行到这里，因为主线程是无限循环）
    pthread_join(receive_thread, NULL);

    // 关闭套接字(close)
    close(socket_fd);

    return 0;
}